package com.buss.core.dao.impl;

import java.util.HashMap;
import java.util.Map;

import org.hibernate.Criteria;
import org.hibernate.SQLQuery;
import org.hibernate.transform.Transformers;
import org.hibernate.type.StandardBasicTypes;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.buss.core.dao.RoleDao;
import com.buss.core.model.Role;
import com.buss.core.model.Sysmenu;
import com.buss.core.model.User;
import com.buss.core.persistence.BaseDao;
import com.buss.core.persistence.OrderBy;
import com.buss.core.persistence.PersistenceCond;
import com.buss.core.persistence.ResultList;

@Repository
public class RoleDaoImpl implements RoleDao {
	
	private static final long serialVersionUID = -676487622516234449L;
	@Autowired
	private BaseDao<Role> baseDao; 

	public void deleteRole(Long[] ids) {
		String hql = "delete from Role role where role.id in (:ids)";
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("ids", ids);
		baseDao.excuteHsql(hql, map);
	}

	public void editRole(Role role) {
		String sql = "update Role role set role.companyId = :companyId," +
				"role.name = :name, " +
				"role.remark = :remark where role.id = :id ";
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("companyId", role.getCompanyId());
		params.put("name", role.getName());
		params.put("remark", role.getRemark());
		params.put("id", role.getId());		
		baseDao.excuteHsql(sql, params);
	}

	public Role loadRole(Long id) {		
		return baseDao.load(id, Role.class);
	}

	public ResultList<Role> queryRole(String companyId,OrderBy orderBy) {		
		String sql = "select role from Role role where role.companyId = :companyId";
		PersistenceCond cond = new PersistenceCond();
		cond.add("companyId", companyId);
		if(orderBy != null){
			sql += orderBy.aggOrder("role");
		}
		return baseDao.queryHsql(sql, cond, null);
	}

	public ResultList<Role> queryRolesByUser(Long userId,OrderBy orderBy){
		String sql = "select * from ( " +
				"select a.id as id,a.name as name,a.remark as remark,1 as checked from core_role a,core_role_user b " +
				" where b.userId=:userId and a.id = b.roleId " +
				" union " +
				" select a.id as id,name as name,a.remark as remark,0 as checked from core_role a " +
				" where a.id not in (select roleId from core_role_user where userId=:userId) " +
				") a order by id "; 
		SQLQuery query = baseDao.getSession().createSQLQuery(sql);
	//	query.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);
		query.addScalar("id", StandardBasicTypes.LONG)
			 .addScalar("name")
			 .addScalar("remark")
			 .addScalar("checked",StandardBasicTypes.BOOLEAN)
			 .setResultTransformer(Transformers.aliasToBean(Role.class));
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("userId", userId);
		if(orderBy != null){
			sql += orderBy.aggOrder("a");
		}
		return baseDao.queryNative(sql, query, params, null);	
		
	}
	
	public void saveRole(Role adminRole) {
		baseDao.save(adminRole);
	}

	public void updateRoleMenu(Role role) {
		String sql = "delete from core_role_menu where roleId=:roleId";
		PersistenceCond cond = new PersistenceCond();
		cond.add("roleId", role.getId());
		baseDao.excuteNative(sql, cond);
		sql = "insert into core_role_menu(roleId,menuId) values(:roleId,:menuId)";
		for(Sysmenu menu : role.getSysmenus()){
			cond = new PersistenceCond();
			cond.add("roleId", role.getId());
			cond.add("menuId", menu.getId());
			baseDao.excuteNative(sql, cond);
		}
	}

	public void updateRoleUser(Role role) {
		String sql = "delete from core_role_user where roleId = :roleId ";
		PersistenceCond cond = new PersistenceCond();
		cond.add("roleId", role.getId());
		baseDao.excuteNative(sql, cond);
		sql = "insert into core_role_user(roleId,userId) values(:roleId,:userId)";
		for(User user : role.getUsers()){
			cond = new PersistenceCond();
			cond.add("roleId", role.getId());
			cond.add("userId", user.getUserId());
			baseDao.excuteNative(sql, cond);
		}		
	}

}
